mod mysql;
mod sqlite;

use model_graph_types::{
    database::{DataSource, DatabaseType},
    transform::{
        DataTransformOptions, DataTransformUnit, DataTransformer, DomainTransformer,
        DomainTransformerFileFormat, DomainTransformerOptions, DomainTransformerUnit,
    },
};

#[derive(Default)]
pub struct DefaultDataTransformer {}

#[async_trait::async_trait]
impl DataTransformer for DefaultDataTransformer {
    /// 根据数据库获取到元数据
    async fn transform(
        &self,
        source: &DataSource,
        target: &DataSource,
        units: Vec<DataTransformUnit>,
        options: DataTransformOptions,
    ) -> anyhow::Result<()> {
        match source.database_type {
            DatabaseType::SQLite => sqlite::transform(source, target, units, options).await,
            DatabaseType::MySQL => mysql::transform(source, target, units, options).await,
            _ => Err(anyhow::anyhow!("不支持的数据类型")),
        }
    }
}

#[async_trait::async_trait]
impl DomainTransformer for DefaultDataTransformer {
    async fn transform_domain(
        &self,
        source: &DataSource,
        target: &DataSource,
        units: Vec<DomainTransformerUnit>,
        options: DomainTransformerOptions,
    ) -> anyhow::Result<()> {
        match source.database_type {
            DatabaseType::SQLite => sqlite::domain_transform(source, target, units, options).await,
            DatabaseType::MySQL => mysql::domain_transform(source, target, units, options).await,
            _ => Err(anyhow::anyhow!("不支持的数据类型")),
        }
    }
    /// 领域数据转移
    async fn write_file(
        &self,
        source: &DataSource,
        target: &String,
        units: Vec<DomainTransformerUnit>,
        options: DomainTransformerOptions,
    ) -> anyhow::Result<()> {
        if let Some(file_optins) = &options.file_options {
            match file_optins.format {
                DomainTransformerFileFormat::SQLite => {
                    sqlite::export_domain_to_file(source, target, units, options).await
                }
                _ => Err(anyhow::anyhow!("不支持的数据类型")),
            }
        } else {
            Err(anyhow::anyhow!("不支持的数据类型"))
        }
    }

    /// 领域数据导入
    async fn read_file(
        &self,
        source: &String,
        target: &DataSource,
        units: Vec<DomainTransformerUnit>,
        options: DomainTransformerOptions,
    ) -> anyhow::Result<()> {
        if let Some(file_optins) = &options.file_options {
            match file_optins.format {
                DomainTransformerFileFormat::SQLite => {
                    sqlite::import_domain_from_file(source, target, units, options).await
                }
                _ => Err(anyhow::anyhow!("不支持的数据类型")),
            }
        } else {
            Err(anyhow::anyhow!("不支持的数据类型"))
        }
    }

    /// 清空领域
    async fn clear_domain(
        &self,
        meta_datasource: &DataSource,
        domains: Vec<String>,
    ) -> anyhow::Result<()> {
        match meta_datasource.database_type {
            DatabaseType::SQLite => sqlite::clear_domain(meta_datasource, domains).await,
            DatabaseType::MySQL => mysql::clear_domain(meta_datasource, domains).await,
            _ => Err(anyhow::anyhow!("不支持的数据类型")),
        }
    }

    /// 删除领域
    async fn delete_domain(
        &self,
        meta_datasource: &DataSource,
        domains: Vec<String>,
    ) -> anyhow::Result<()> {
        match meta_datasource.database_type {
            DatabaseType::SQLite => sqlite::delete_domain(meta_datasource, domains).await,
            DatabaseType::MySQL => mysql::delete_domain(meta_datasource, domains).await,
            _ => Err(anyhow::anyhow!("不支持的数据类型")),
        }
    }
}
